package pluginUtils.geneticAlgorithms;

import java.util.ArrayList;
import java.util.Random; 

public class Population {
	private ArrayList<Genome> people=new ArrayList<Genome>();
	
	private static Random generator=new Random(); 
	
	public Population(int taille) throws Exception{
		for(int i=0;i<taille;i++)
			people.add(Genome.createGenome(5)); 
	}
	
	public Genome get(int i){
			return people.get(i); 
	}

	public void evolve(double[] fitnessArray) throws Exception{
		double v;
		int k; 
		System.out.println("this.getSize() "+this.getSize()); 
		// select (roulette wheel nb individuals
		Population virginie=new Population(0); 
		
		double maxi=fitnessArray[fitnessArray.length-1]; 
		for(int i=0;i<this.getSize()/2;i++){ 
			v=generator.nextDouble()*maxi;
			k=0; while(v>fitnessArray[k])k++; 
			virginie.people.add(this.get(k));
			
		}
		// Cross-over
		for(int i=0;i<this.getSize()/4;i++){
		v=generator.nextDouble()*maxi;
		k=0; while(v>fitnessArray[k])k++; 
		Genome father=this.get(k);
		v=generator.nextDouble()*maxi;
		k=0; while(v>fitnessArray[k])k++; 
		Genome mother=this.get(k);
		Genome son1=Genome.createVoidGenome(); 
		Genome son2=Genome.createVoidGenome(); 
		generate(father,mother,son1,son2); 
		virginie.people.add(son1); 
		virginie.people.add(son2);
		
		}
		//mutation
		for(int i=0;i<this.getSize();i++){
			if(generator.nextDouble()<1e-4){ // mutation of circle i
				Genome gege=this.people.get(i);
				int j=generator.nextInt(gege.getLength());
				gege.add(j,new Cercle(Genome.getX(),Genome.getY()));
			
			}//if
			
		}// for i
		
		this.people=new ArrayList<Genome>(virginie.people); 
		
	
	}

	private void generate(Genome f,Genome m,Genome s1,Genome s2) {
		int bf=generator.nextInt(f.getLength()); 
		int bm=generator.nextInt(m.getLength()); 
		// build s1
		for(int i=0;i<bf;i++) s1.add(f.get(i)); 
		for(int i=bm;i<m.getLength();i++) s1.add(m.get(i)); 
		// build s2
		for(int i=0;i<bm;i++) s2.add(m.get(i)); 
		for(int i=bf;i<f.getLength();i++) s2.add(f.get(i)); 	
	}

	public int getSize() {
		return this.people.size();
	}

}
